package com.rao.config.websecurity.permitcollect;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Set;

@Component
public class ConfigurableListableBeanFactoryUtil implements BeanFactoryPostProcessor,
        ApplicationContextAware {
    public static ConfigurableListableBeanFactory configurableListableBeanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        configurableListableBeanFactory = beanFactory;
    }

    /*
     触发自定义的事件  refresh()-->registerListeners();
     // Publish early application events now that we finally have a multicaster...
     		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;// this.earlyApplicationEvents，size是0，所以 todo 突破点
     		this.earlyApplicationEvents = null;
     		if (earlyEventsToProcess != null) {
     			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                  //todo 触发spring事件回调机制
     				getApplicationEventMulticaster().multicastEvent(earlyEvent);
     先后顺序问题
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (applicationContext instanceof AnnotationConfigServletWebServerApplicationContext) {
            Class<AbstractApplicationContext> abstractApplicationContextClass = AbstractApplicationContext.class;
            try {
                Field earlyApplicationEvents = abstractApplicationContextClass
                        .getDeclaredField("earlyApplicationEvents");
                earlyApplicationEvents.setAccessible(true);
                Set<ApplicationEvent> events = (Set<ApplicationEvent>) earlyApplicationEvents.get(applicationContext);
                events.add(new SecurityEvent("rao3030==`wahaha"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
